package cn.com.jinhao.provider.business.service.impl;


import cn.com.jinhao.hotline.commons.base.constant.SystemConstant;
import cn.com.jinhao.hotline.commons.exception.BusinessErrorException;
import cn.com.jinhao.hotline.commons.util.ExeclUtil;
import cn.com.jinhao.hotline.commons.util.RestResponse;
import cn.com.jinhao.hotline.commons.vo.business.HistoryDispatchResponseVO;
import cn.com.jinhao.hotline.commons.vo.business.LinkManInDeptResponseVO;
import cn.com.jinhao.hotline.commons.vo.business.RecordInfoRequestVO;
import cn.com.jinhao.hotline.commons.vo.business.dispatch.DispatchCondition;
import cn.com.jinhao.provider.business.entity.Dispatch;
import cn.com.jinhao.provider.business.mapper.DispatchMapper;
import cn.com.jinhao.provider.business.service.AttachService;
import cn.com.jinhao.provider.business.service.DispatchService;
import cn.com.jinhao.provider.business.service.FeignService;
import cn.com.jinhao.provider.business.service.RecordInfoService;
import cn.com.jinhao.provider.business.vo.DispatchInfoRequestVO;
import cn.com.jinhao.hotline.commons.vo.user.OrganizerResponseVO;
import cn.com.jinhao.provider.business.vo.DispatchReqeustVo;
import cn.com.jinhao.provider.business.vo.MemoInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.*;

/**
 * HotLine
 * <p>Description: 派单业务逻辑实现类</p>
 *
 * @author ShaneMew
 * @version 1.0
 * @date 2020/02/17
 * @since 2020/02/17
 */

@Service
public class DispatchServiceImpl extends CommonService implements DispatchService {
    @Resource
    private DispatchMapper dispatchMapper;
    @Resource
    AttachService attachService;
    @Resource
    private RecordInfoService recordInfoService;
    @Resource
    private FeignService feignService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addBatch(DispatchReqeustVo dispatchReqeustVo) throws Exception {
//            List<Attach> attaches = dispatchReqeustVo.getAttaches();
//            attachMapper.insertList(attaches);
        List<Dispatch> dispatchList = dispatchReqeustVo.getDispatches();
//            List<Dispatch> dataDispatches = new ArrayList<>(10);
        for (Dispatch dispatch : dispatchList) {
            Optional.ofNullable(recordInfoService.selectByCode(dispatch.getEventInformationCode())).orElseThrow(() -> new BusinessErrorException("事件不存在"));
            dispatch.setCode(getCode(SystemConstant.CodeType.COMPLEX) + dispatch.getEventInformationCode());
            validateDispatch(dispatch, dispatch.getEventInformationCode());
            supplementInfo(dispatch);
//                dataDispatches.add(dataDispatch);
        }
        dispatchMapper.insertList(dispatchList);
//            updateByEventCode(dataDispatch.getEventInformationCode(), dataDispatch.getStDeptCodeA(), dataDispatch.getCode());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addDirectBatch(DispatchInfoRequestVO dispatchInfoRequestVO) throws Exception {
        RecordInfoRequestVO recordInfoRequestVO = dispatchInfoRequestVO.getRecordInfoRequestVO();
        List<Dispatch> dispatchList = dispatchInfoRequestVO.getDispatches();
        String eventCode = recordInfoService.add(recordInfoRequestVO);
//            List<Dispatch> dataDispatches = new ArrayList<>(10);
        for (Dispatch dispatch : dispatchList) {
            validateDispatch(dispatch, eventCode);
            supplementInfo(dispatch);
//                dataDispatches.add(dataDispatch);
            // 流程状态暂停
//           updateByEventCode(dataDispatch.getEventInformationCode(),dataDispatch.getStDeptCodeA(),dataDispatch.getCode());
        }
        dispatchMapper.insertList(dispatchList);
    }


    private void supplementInfo(Dispatch dispatch) {
        dispatch.setEvas(super.getDetailMsg(dispatch.getStDeptDeptA(), dispatch.getStDeptDeptB(), SystemConstant.Operation.DISPATCH.getName(), dispatch.getCode()));
        int beginStr = dispatch.getStTlbkTlbk().indexOf("-");
        int endStr = dispatch.getStTlbkTlbk().lastIndexOf("-");
        String toOperator = dispatch.getStTlbkTlbk().substring(beginStr,endStr);
        MemoInfo memoInfo = MemoInfo.builder().code(dispatch.getCode()).eventCode(dispatch.getEventInformationCode())
            .fromDept(dispatch.getStDeptDeptA()).toDept(dispatch.getStDeptDeptB())
            .fromOperator(dispatch.getStOperOperA()).toOperator(toOperator)
            .way(dispatch.getDispatchWay()).build();
        dispatch.setMemo(super.getMemo(memoInfo));
    }

    private void validateDispatch(Dispatch dispatch, String eventCode) throws Exception {
        String deptCodeA = dispatch.getStDeptCodeA();
        String deptCodeB = dispatch.getStDeptCodeB();
        // 获取派单部门名称

       Optional.ofNullable(feignService.queryDeptNameByCode(deptCodeA)).orElseThrow(() -> new BusinessErrorException("派单部门错误"));


        // 获取接单部门名称
        String deptB = Optional.ofNullable(feignService.queryDeptNameByCode(deptCodeB)).orElseThrow(() -> new BusinessErrorException("接单部门错误"));

        // 验证接单部门下是否存在联系人信息
        RestResponse<java.util.List<LinkManInDeptResponseVO>> linkManB = feignService.queryLinkManByDeptCode(deptCodeB);
        Optional.ofNullable(linkManB.getData()).orElseThrow(() -> new BusinessErrorException("接单部门: " + deptB + "下不存在联系人"));


        List<LinkManInDeptResponseVO> linkManInfoBes = JSONObject.parseArray(JSON.toJSONString(linkManB.getData()), LinkManInDeptResponseVO.class);

        if (!feignService.checkUserByCodeAndDept(dispatch.getStOperCodeA(), deptCodeA)) {
            throw new BusinessErrorException("派单人不存在");
        }

        // 验证接单部门联系人编码
        String blankStr = " ";
        if (linkManInfoBes.stream().noneMatch(s -> s.getCode().equals(dispatch.getStTlbkCode()) && s.getLinkManInfo().replaceAll(blankStr, "").equals(dispatch.getStTlbkTlbk().replaceAll(blankStr, "")))) {
            throw new BusinessErrorException("承办部门联系人错误");
        }

        if (isExist(eventCode, dispatch.getStDeptCodeB())) {
            throw new BusinessErrorException("错误: 不允许多次派发给同一个承办部门");
        }
        dispatch.setEventInformationCode(eventCode);
        dispatch.setCode(getCode(SystemConstant.CodeType.COMPLEX) + eventCode);
    }

    private boolean isExist(String eventCode, String deptCode) {
        Example example = new Example(Dispatch.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("eventInformationCode", eventCode);
        criteria.andEqualTo("stDeptCodeB", deptCode);
        criteria.andEqualTo("reject", 0);
        criteria.andEqualTo("deny", 0);
        criteria.andEqualTo("stat", 1);
        Dispatch dispatch = dispatchMapper.selectOneByExample(example);
        return Optional.ofNullable(dispatch).isPresent();
    }

    @Override
    public int update(Dispatch dispatch){
        Example example = new Example(Dispatch.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("code", dispatch.getCode());
        supplementInfo(dispatch);
        return dispatchMapper.updateByExample(dispatch, example);
    }

    @Override
    public List<HistoryDispatchResponseVO> historyDispatch(String eventCode) {

        return dispatchMapper.selectHistory(eventCode);
    }

    @Override
    public OrganizerResponseVO updateOrganizerDispatch(String eventCode, String deptCode) {
        return updateOrganizer(eventCode, deptCode);
    }

    @Override
    public Dispatch selectByCode(String code) {
        Dispatch dispatch = new Dispatch();
        dispatch.setCode(code);
        return dispatchMapper.selectOne(dispatch);
    }

    @Override
    public void deleteByCode(String code) {
        Example example = new Example(Dispatch.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("code", code);
        dispatchMapper.deleteByExample(example);
    }

    @Override
    public Map<String,Object> listDispatchByCancel(String deptCode, int pageNo, int pageSize) throws Exception {
        DispatchCondition dispatchCondition = new DispatchCondition();
        dispatchCondition.setStDeptCodeA(deptCode);
        dispatchCondition.setIsExport(false);
        dispatchCondition.setPageNo(pageNo);
        dispatchCondition.setPageSize(pageSize);
        return this.selectByCondition(dispatchCondition);
    }

    @Override
    public Map<String, Object> selectByCondition(DispatchCondition conditions) throws Exception {
        HashMap<String, Object> map = new HashMap<>(10);
        Example example = getExample(conditions);
        if (conditions.getIsExport()) {
            List<Dispatch> dispatches = dispatchMapper.selectByExample(example);
            List<String> headers = conditions.getHeaders();
            JSONArray jsonArray = JSONArray.parseArray(JSON.toJSONString(dispatches));
            String fileInfo = new ExeclUtil().exportExecl(headers,jsonArray,"F:\\");
            map.put("fileInfo", fileInfo);
        }else {
            if (conditions.getPageNo() != 0 && conditions.getPageSize() != 0) {
                PageHelper.startPage(conditions.getPageNo(), conditions.getPageSize());
                PageInfo<Dispatch> pageInfo = new PageInfo<>(dispatchMapper.selectByExample(example));
                map.put("list", pageInfo);
                map.put("total", pageInfo.getTotal());
                map.put("pageSize", pageInfo.getPageSize());
                map.put("pageNo", pageInfo.getPageNum());
            } else {
                List<Dispatch> dispatches = dispatchMapper.selectByExample(example);
                map.put("list", dispatches);
                map.put("total", dispatches.size());
            }
        }
        return map;
    }

    Example getExample(DispatchCondition conditions) {
        Example example = new Example(Dispatch.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isFinish",0);
        criteria.andEqualTo("isFeedback", 0);
        criteria.andEqualTo("isCancel", 0);
        if (StringUtils.isNotBlank(conditions.getStDeptCodeA())) {
            criteria.andEqualTo("stDeptCodeA", conditions.getStDeptCodeA());
        }
        example.setOrderByClause("'createTime' desc, 'modifyTime' desc");
        return example;
    }
}
